﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.OleDb;

namespace Meqs.Logic.Core
{
    /// <summary>
    /// 数据库类型
    /// dzf
    /// </summary>
    public enum DBType
    {
        MsSQL,      //sql server 2000/2005
        OracleSQL   //Oracle
    }

    /// <summary>
    /// 存储过程输入输出参数的类型
    /// dzf
    /// 
    /// </summary>
    public enum DBParameterDirection
    {
        Input = ParameterDirection.Input,   //参数为输入参数
        InputOutput = ParameterDirection.InputOutput,//参数为输入输出参数
        Output = ParameterDirection.Output,//参数为输出参数
        ReturnValue = ParameterDirection.ReturnValue   //参数为返回值类型
    }

    /// <summary>
    /// 存储过程参数的类型
    /// </summary>
    public enum DBParamerType
    {
        BigInt,
        Binary,
        Char,
        DBDateTime,
        Decimal,
        Float,
        SmallInt,
        TinyInt,
        VarBinary,
        VarChar,
        Variant,
        Integer
    }

    /// <summary>
    /// 数据库操作接口
    /// </summary>
    public interface IDBAccess
    {
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="strServer">地址</param>
        /// <param name="port">端口</param>
        /// <param name="strDataBase">数据库名</param>
        /// <param name="strUser">帐号</param>
        /// <param name="strPwd">密码</param>
        void Init(string strServer, string port, string strDataBase, string strUser, string strPwd);
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="strServer">地址</param>
        void Init(string strServer);
        /// <summary>
        /// 打开数据库
        /// </summary>
        void Open();

        /// <summary>
        /// 关闭数据库
        /// </summary>
        void Close();

        /// <summary>
        /// 执行非查询得SQL
        /// </summary>
        /// <param name="strCmd">执行语句</param>
        /// <returns>返回影响行数</returns>
        int RunNoQuery(string strCmd);
        int RunNoQuery(string strCmd, string name, byte[] image, long len);
        int RunNoQuery(string strCmd, string[] name, object[] paramer);
        int RunNoQuery(string insertStrCmd, string[] name, object[] paramer, ref int newNum);
        /// <summary>
        /// 执行查询SQL
        /// </summary>
        /// <param name="strCmd">执行sql</param>
        /// <returns>查询到得数据</returns>
        DataTable RunQuery(string strCmd);
        DataTable RunQuery(string strCmd, string[] name, object[] paramer);
        /// <summary>
        /// 获得当前数据库类型
        /// </summary>
        DBType DBType { get;}

        /// <summary>
        /// 获得某字段(整型字段)的最大值
        /// </summary>
        /// <param name="strTable">表名</param>
        /// <param name="strField">字段名</param>
        /// <returns></returns>
        int GetFiledMax(string strTable, string strField);

        /// <summary>
        /// 返回数据库中所有表的信息
        /// </summary>
        DataTable Tables { get; }

        /// <summary>
        /// 返回所有表的列信息
        /// </summary>
        /// <returns>字段信息</returns>
        DataTable GetColumns();

        /// <summary>
        /// 返回一张表的列信息
        /// </summary>
        /// <param name="strTable">表名</param>
        /// <returns>表信息</returns>
        DataTable GetColumns(string strTable);

        /// <summary>
        /// 执行非查询类存储过程
        /// </summary>
        /// <param name="procName">存储过程名</param>
        /// <param name="ParaValue">参数类标</param>
        /// <param name="ParaName">参数名列表</param>
        /// <param name="ParaType">参数类型列表</param>
        /// <param name="ParaDire">参数传入传出列表</param>
        void ExecProcNonQuery(string procName, object[] ParaValue, string[] ParaName, DBParamerType[] ParaType, DBParameterDirection[] ParaDire);

        /// <summary>
        /// 执行查询类存储过程
        /// </summary>
        /// <param name="procName">存储过程名</param>
        /// <param name="ParaValue">参数类标</param>
        /// <param name="ParaName">参数名列表</param>
        /// <param name="ParaType">参数类型列表</param>
        /// <param name="ParaDire">参数传入传出列表</param>
        /// <returns>查询得到了结果集</returns>
        DataTable ExecProcQuery(string procName, object[] ParaValue, string[] ParaName, DBParamerType[] ParaType, DBParameterDirection[] ParaDire);

        /// <summary>
        /// 更新datatable中所有的信息
        /// </summary>
        /// <param name="strTblName">表名</param>
        /// <param name="dt">需要更新的DT</param>
        /// <param name="pk">修改依据的主键</param>
        /// <returns>返回所有的影响行数</returns>
        int UpdateDataTable(string strTblName, DataTable dt, string pk);

        /// <summary>
        /// 开始事务
        /// </summary>
        /// <returns></returns>
        object StartTransaction();
        /// <summary>
        /// 提交事务
        /// </summary>
        /// <param name="sign"></param>
        void CommitTransaction(object sign);
        /// <summary>
        /// 回滚事务
        /// </summary>
        /// <param name="sign"></param>
        void RollBackTransaction(object sign);
    }

    /// <summary>
    /// 工厂类
    /// dzf
    /// </summary>
    public static class DBAccessFactory
    {
        //操作接口
        private static IDBAccess IRet = null;

        /// <summary>
        /// 单例,获取操作接口
        /// </summary>
        /// <param name="type">数据库类型</param>
        /// <returns>操作接口</returns>
        public static IDBAccess CreateInstance(DBType type)
        {
            if (IRet == null)
            {
                DBAccess IObj = null;
                switch (type)
                {
                    //case DBType.OracleSQL:
                    //    IObj = new OracleSQL(type);
                    //    break;

                    case DBType.MsSQL:
                        IObj = new MsSQL(type);
                        break;

                    default:
                        throw new DBServiceException("无此数据库类型",null);

                }
                IRet = new DBAccessProxy(IObj);
            }

            return IRet;
        }
        /// <summary>
        /// 单例,获取操作接口
        /// </summary>
        /// <returns>操作接口</returns>
        public static IDBAccess GetInstance()
        {
            return IRet;
        }
    }
}